import json
import os.path
import pathlib
import subprocess

import requests
from playwright.async_api import async_playwright

from result import Result

use_uno = os.getenv("USE_UNO") == 'true'


async def convert_file_format(input_path: str, output_path: str):
    if os.path.exists(output_path):
        return

    _, input_ext = os.path.splitext(input_path)
    input_ext = input_ext[1:].lower()
    output_base, output_ext = os.path.splitext(output_path)
    output_ext = output_ext[1:].lower()

    if input_ext == 'html' and output_ext == 'pdf':
        await html_to_pdf(input_path, output_path)
        return

    if input_ext == 'html' and output_ext == 'png':
        await html_to_png(input_path, output_path)
        return

    if input_ext == 'html' and output_ext == 'docx':
        pdf_path = f'{output_base}.pdf'
        await html_to_pdf(input_path, pdf_path)
        await extra_convert_file_format(pdf_path, output_path)
        return

    if input_ext == 'pdf' and output_ext == 'docx':
        await extra_convert_file_format(input_path, output_path)
        return

    if output_ext == 'md':
        subprocess.run(['pandoc', input_path, '-o', output_path],
                       check=True, capture_output=True, text=True, timeout=60)
        if os.path.exists(output_path):
            return

    if use_uno:
        subprocess.run(['unoconvert', '--convert-to', output_ext, input_path, output_path],
                       check=True, capture_output=True, text=True, timeout=60)
    else:
        out_dir = os.path.dirname(output_path)
        subprocess.run(['soffice', '--headless', '--convert-to', output_ext, input_path, '--outdir', out_dir],
                       check=True, capture_output=True, text=True, timeout=60)
        converted_path = os.path.join(out_dir, pathlib.Path(input_path).stem + '.' + output_ext)
        if converted_path != output_path:
            os.rename(converted_path, output_path)
    if os.path.exists(output_path):
        return

    if input_ext == 'pdf' or input_ext == 'doc' or input_ext == 'docx':
        await extra_convert_file_format(input_path, output_path)
        return


async def html_to_pdf(input_path: str, output_path: str):
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=True)
        page = await browser.new_page()
        await page.goto(f'file://{input_path}')
        pdf_options = {
            'path': output_path,
            'format': 'A4',
            'print_background': True,
        }
        await page.pdf(**pdf_options)
        await browser.close()


async def html_to_png(input_path: str, output_path: str):
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=True)
        page = await browser.new_page()
        await page.goto(f'file://{input_path}')
        screenshot_options = {
            'path': output_path,
            'full_page': True,
        }
        await page.screenshot(**screenshot_options)
        await browser.close()


async def extra_convert_file_format(input_path: str, output_path: str):
    url = 'http://localhost:8888/convert-file-format'
    data = {'input_path': input_path, 'output_path': output_path}
    headers = {'Content-Type': 'application/json'}

    response = requests.post(url, data=json.dumps(data), headers=headers)
    if response.status_code == 200:
        rt = Result.json_to_result(response.text)
        if not rt.success:
            raise Exception(f'Failed to convert file format: {rt.message}')
    else:
        raise Exception(f'Failed to convert file format: {response.status_code}')


def get_file_extension(file_path):
    if not file_path:
        return ""
    root, ext = os.path.splitext(file_path)
    return ext.lower() if ext else ""
